package view;

import model.SpelObject;
import model.GameMap;
import model.Richting;
import model.Veld;
import model.BeweegVijand;
import model.Path;
import model.Vijand;
import model.Opties;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Timer;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
 *
 * @author Alvin & Roy
 */
public class SpelOmgeving extends javax.swing.JPanel {

    /** De locatie van plaatjes */
    private final String IPATH = System.getProperty("user.dir") + "\\res\\";
    /** De grote van de vakjes */
    private static final int VELDGROOTTE = 20;

    /** Is het spel gepauzeerd */
    private boolean pauze;

    /** De timer */
    private Timer timer;

    /** De game map uit de model package */
    private GameMap map;

    /** Moet het pad van de vijand getekend worden */
    private static boolean tekenPad;

    /** Het plaatje voor het pad */
    private Image padImg;

    /**
     * De constructor
     * @param verticaleVelden Het aantal verticale velden
     * @param horizontaleVelden Het aantal horizontale velden
     * @param beweegbareObstakels Het aantal beweegbare obstakels
     * @param onbeweegbareObstakels Het aantal onbeweegbare obstakels
     */
    public SpelOmgeving(int horizontaleVelden,int verticaleVelden, 
            int beweegbareObstakels, int onbeweegbareObstakels, Main m){

        //maak een nieuwe game map aan
        map = new GameMap(verticaleVelden, horizontaleVelden, 
                beweegbareObstakels, onbeweegbareObstakels, this);

        //maak het paneel
        this.setSize(horizontaleVelden*VELDGROOTTE+1, verticaleVelden*VELDGROOTTE+1);
        this.setBackground(new Color(204,153,0));
        
        //maak de Key Listener
        KeyListener keyListener = new MovementListener();
        addKeyListener(keyListener);
        setFocusable(true);

        //maak de timer
        timer = new Timer();
        for(Vijand vijand : map.getVijanden()){
            timer.schedule(new BeweegVijand(vijand, m), Opties.getVijandSnelheid(), Opties.getVijandSnelheid());
        }
        
        //stel teken pad in
        tekenPad = Opties.getShowPath();
        
        //haal het plaatje voor het pad op
        try {
            padImg = ImageIO.read(new File(IPATH+"death.png"));
        } catch (IOException e) {
                System.out.println("Fout bij het laden van de recources: " + e);
                System.exit(0);
        }

    }

    /**
     * Constructor van spelomgeving voor een lege spelwereld
     * -Deze constructor wordt alleen gebruikt bij de unit tests!!-
     * @param verticaleVelden Het aantal horizontale velden
     * @param horizontaleVelden Het aantal verticale velden
     */
    public SpelOmgeving(int verticaleVelden, int horizontaleVelden){

        //maak een nieuwe game map aan
        map = new GameMap(verticaleVelden, horizontaleVelden, this);

        //maak het paneel
        this.setSize(horizontaleVelden*VELDGROOTTE+1, verticaleVelden*VELDGROOTTE+1);
        this.setBackground(new Color(204,153,0));
        setFocusable(true);

        //stel teken pad in, standaard false
        tekenPad = false;
    }

    /**
     * Override van de paintComponent van JLabel
     * @see JLabel.paintComponent
     * @param g De graphics
     */
    public void paintComponent(Graphics g){
        //roep de paint van de super aan
        super.paintComponent(g);

        //maak een tijdelijke variabele voor de velden aan
        //haal de velden op uit de game map
        Veld velden[][] = map.getVelden();

        //teken alle objecten
        for(int i = 0; i<velden.length;i++){
            for(int j = 0; j<velden[0].length;j++){
                if(velden[i][j].getSpelObject() != null){
                    SpelObject o = velden[i][j].getSpelObject();
                    int x = velden[i][j].getXPos();
                    int y = velden[i][j].getYPos();
                    g.drawImage(o.getImg(), x*VELDGROOTTE, y*VELDGROOTTE, null);
                }
            }
        }

        g.setColor(Color.black);
        //teken de horizontale lijnen
        for(int i = 0; i<=velden[0].length; i++){
            g.drawLine(0, i*VELDGROOTTE, velden.length*VELDGROOTTE, i*VELDGROOTTE);
        }

        //teken de verticale lijnen
        for(int i = 0; i<=velden.length;i++){
            g.drawLine(i*VELDGROOTTE, 0, i*VELDGROOTTE, velden[0].length*VELDGROOTTE);
        }

        //teken het pad
        tekenPad(g);
    }

    /**
     * Teken het pad van de vijand
     * @param g De graphics
     */
    public void tekenPad(Graphics g){
        if(tekenPad){
            for(Vijand vijand : map.getVijanden()){
                Path pad = vijand.getLaatstePad();
                if(pad != null){
                    for(int i = 2; i<pad.getLength()-1; i++){
                        int x = pad.getStep(i).getX();
                        int y = pad.getStep(i).getY();

                        x = x*VELDGROOTTE;
                        y = y*VELDGROOTTE;

                        g.drawImage(padImg, x, y, null);
                    }
                }
            }
        }
    }

    class MovementListener implements KeyListener{

        /**
         * @see KeyListener#keyPressed(java.awt.event.KeyEvent) 
         */
        public void keyPressed(KeyEvent e){
            
        }

        /**
         * @see KeyListener#keyReleased(java.awt.event.KeyEvent)
         */
        public void keyReleased(KeyEvent e){
            if(!pauze){
                switch(e.getKeyCode()){
                    case KeyEvent.VK_UP:
                        map.getSpeler().move(Richting.N);
                        break;
                    case KeyEvent.VK_RIGHT:
                        map.getSpeler().move(Richting.O);
                        break;
                    case KeyEvent.VK_DOWN:
                        map.getSpeler().move(Richting.Z);
                        break;
                    case KeyEvent.VK_LEFT:
                        map.getSpeler().move(Richting.W);
                        break;
                    default:
                        break;
                }
            }
        }

        /**
         * @see KeyListener#keyTyped(java.awt.event.KeyEvent) KeyTyped
         * @param e
         */
        public void keyTyped(KeyEvent e){
            
        }
    }

    /**
     * Haal de veld grootte op
     * @return De veld grootte
     */
    public static int getVeldgrootte(){
        return VELDGROOTTE;
   }

    /**
     * Haal de map op
     * @return De map
     */
   public GameMap getMap(){
       return map;
   }

   /**
    * Stel pauze in
    * Pauze wordt de tegenovergestelde waarde van de huidige waarde
    */
   public void togglePauze(){
       pauze = !pauze;

       for(Vijand vijand : map.getVijanden()){
           vijand.toggleMagBewegen();
       }
   }

   /**
    * Controleer of het spel gepauzeerd is
    * @return True als het spel gepauzeerd is
    */
   public boolean isPaused(){
       return pauze;
   }

   /**
    * Stel show path in
    * Wordt de tegenovergestelde waarde van de huidige waarde
    */
   public static void toggleShowPath(){
       tekenPad = Opties.getShowPath();
   }
}



